home *** CD-ROM | disk | FTP | other *** search
/ Visual Cafe 3 / Visual Cafe 3.ISO / Vcafe / Main.bin / DateFormatSymbols.java < prev    next >
Text File  |  1998-09-22  |  16KB  |  451 lines

  1. /*
  2.  * @(#)DateFormatSymbols.java    1.20 98/01/12
  3.  *
  4.  * (C) Copyright Taligent, Inc. 1996 - All Rights Reserved
  5.  * (C) Copyright IBM Corp. 1996 - All Rights Reserved
  6.  *
  7.  * Portions copyright (c) 1996 Sun Microsystems, Inc. All Rights Reserved.
  8.  *
  9.  *   The original version of this source code and documentation is copyrighted
  10.  * and owned by Taligent, Inc., a wholly-owned subsidiary of IBM. These
  11.  * materials are provided under terms of a License Agreement between Taligent
  12.  * and Sun. This technology is protected by multiple US and International
  13.  * patents. This notice and attribution to Taligent may not be removed.
  14.  *   Taligent is a registered trademark of Taligent, Inc.
  15.  *
  16.  * Permission to use, copy, modify, and distribute this software
  17.  * and its documentation for NON-COMMERCIAL purposes and without
  18.  * fee is hereby granted provided that this copyright notice
  19.  * appears in all copies. Please refer to the file "copyright.html"
  20.  * for further important copyright and licensing information.
  21.  *
  22.  * SUN MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY OF
  23.  * THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
  24.  * TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
  25.  * PARTICULAR PURPOSE, OR NON-INFRINGEMENT. SUN SHALL NOT BE LIABLE FOR
  26.  * ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  27.  * DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
  28.  *
  29.  */
  30.  
  31. package java.text;
  32. import java.util.Locale;
  33. import java.util.ResourceBundle;
  34. import java.io.Serializable;
  35. import java.util.Hashtable;
  36.  
  37. /**
  38.  * <code>DateFormatSymbols</code> is a public class for encapsulating
  39.  * localizable date-time formatting data, such as the names of the
  40.  * months, the names of the days of the week, and the time zone data.
  41.  * <code>DateFormat</code> and <code>SimpleDateFormat</code> both use
  42.  * <code>DateFormatSymbols</code> to encapsulate this information.
  43.  *
  44.  * <p>
  45.  * Typically you shouldn't use <code>DateFormatSymbols</code> directly.
  46.  * Rather, you are encouraged to create a date-time formatter with the
  47.  * <code>DateFormat</code> class's factory methods: <code>getTimeInstance</code>,
  48.  * <code>getDateInstance</code>, or <code>getDateTimeInstance</code>. 
  49.  * These methods automatically create a <code>DateFormatSymbols</code> for
  50.  * the formatter so that you don't have to. After the
  51.  * formatter is created, you may modify its format pattern using the
  52.  * <code>setPattern</code> method. For more information about
  53.  * creating formatters using <code>DateFormat</code>'s factory methods,
  54.  * see <a href="java.text.DateFormat.html"><code>DateFormat</code></a>.
  55.  *
  56.  * <p>
  57.  * If you decide to create a date-time formatter with a specific
  58.  * format pattern for a specific locale, you can do so with:
  59.  * <blockquote>
  60.  * <pre>
  61.  * new SimpleDateFormat(aPattern, new DateFormatSymbols(aLocale)).
  62.  * </pre>
  63.  * </blockquote>
  64.  *
  65.  * <p>
  66.  * <code>DateFormatSymbols</code> objects are clonable. When you obtain
  67.  * a <code>DateFormatSymbols</code> object, feel free to modify the
  68.  * date-time formatting data. For instance, you can replace the localized
  69.  * date-time format pattern characters with the ones that you feel easy
  70.  * to remember. Or you can change the representative cities
  71.  * to your favorite ones.
  72.  *
  73.  * <p>
  74.  * New <code>DateFormatSymbols</code> subclasses may be added to support
  75.  * <code>SimpleDateFormat</code> for date-time formatting for additional locales.
  76.  
  77.  * @see          DateFormat
  78.  * @see          SimpleDateFormat
  79.  * @see          java.util.SimpleTimeZone
  80.  * @version      1.20 01/12/98
  81.  * @author       Chen-Lieh Huang
  82.  */
  83. public class DateFormatSymbols implements Serializable, Cloneable {
  84.  
  85.     /**
  86.      * Construct a DateFormatSymbols object by loading format data from
  87.      * resources for the default locale.
  88.      *
  89.      * @exception  java.util.MissingResourceException
  90.      *             if the resources for the default locale cannot be
  91.      *             found or cannot be loaded.
  92.      */
  93.     public DateFormatSymbols()
  94.     {
  95.         initializeData(Locale.getDefault());
  96.     }
  97.  
  98.     /**
  99.      * Construct a DateFormatSymbols object by loading format data from
  100.      * resources for the given locale.
  101.      *
  102.      * @exception  java.util.MissingResourceException
  103.      *             if the resources for the specified locale cannot be
  104.      *             found or cannot be loaded.
  105.      */
  106.     public DateFormatSymbols(Locale locale)
  107.     {
  108.         initializeData(locale);
  109.     }
  110.  
  111.     /**
  112.      * Era strings. For example: "AD" and "BC".
  113.      */
  114.     String eras[] = null;
  115.     /**
  116.      * Month strings. For example: "January", "February", etc.
  117.      */
  118.     String months[] = null;
  119.     /**
  120.      * Short month strings. For example: "Jan", "Feb", etc.
  121.      */
  122.     String shortMonths[] = null;
  123.     /**
  124.      * Weekday strings. For example: "Sunday", "Monday", etc.
  125.      */
  126.     String weekdays[] = null;
  127.     /**
  128.      * Short weekday strings. For example: "Sun", "Mon", etc.
  129.      */
  130.     String shortWeekdays[] = null;
  131.     /**
  132.      * Ampm strings. For example: "AM" and "PM".
  133.      */
  134.     String ampms[] = null;
  135.     /**
  136.      * The format data of all the timezones in this locale.
  137.      */
  138.     String zoneStrings[][] = null;
  139.     /**
  140.      * Unlocalized date-time pattern characters. For example: 'y', 'd', etc.
  141.      * All locales use the same these unlocalized pattern characters.
  142.      */
  143.     static final String  patternChars = "GyMdkHmsSEDFwWahKz";
  144.     /**
  145.      * Localized date-time pattern characters. For example: use 'u' as 'y'.
  146.      */
  147.     String  localPatternChars = null;
  148.  
  149.     static final long serialVersionUID = -5987973545549424702L;
  150.  
  151.     /**
  152.      * Gets era strings. For example: "AD" and "BC".
  153.      * @return the era strings.
  154.      */
  155.     public String[] getEras() {
  156.         return duplicate(eras);
  157.     }
  158.  
  159.     /**
  160.      * Sets era strings. For example: "AD" and "BC".
  161.      * @param newEras the new era strings.
  162.      */
  163.     public void setEras(String[] newEras) {
  164.         eras = duplicate(newEras);
  165.     }
  166.  
  167.     /**
  168.      * Gets month strings. For example: "January", "February", etc.
  169.      * @return the month strings.
  170.      */
  171.     public String[] getMonths() {
  172.         return duplicate(months);
  173.     }
  174.  
  175.     /**
  176.      * Sets month strings. For example: "January", "February", etc.
  177.      * @param newMonths the new month strings.
  178.      */
  179.     public void setMonths(String[] newMonths) {
  180.         months = duplicate(newMonths);
  181.     }
  182.  
  183.     /**
  184.      * Gets short month strings. For example: "Jan", "Feb", etc.
  185.      * @return the short month strings.
  186.      */
  187.     public String[] getShortMonths() {
  188.         return duplicate(shortMonths);
  189.     }
  190.  
  191.     /**
  192.      * Sets short month strings. For example: "Jan", "Feb", etc.
  193.      * @param newShortMonths the new short month strings.
  194.      */
  195.     public void setShortMonths(String[] newShortMonths) {
  196.         shortMonths = duplicate(newShortMonths);
  197.     }
  198.  
  199.     /**
  200.      * Gets weekday strings. For example: "Sunday", "Monday", etc.
  201.      * @return the weekday strings.
  202.      */
  203.     public String[] getWeekdays() {
  204.         return duplicate(weekdays);
  205.     }
  206.  
  207.     /**
  208.      * Sets weekday strings. For example: "Sunday", "Monday", etc.
  209.      * @param newWeekdays the new weekday strings.
  210.      */
  211.     public void setWeekdays(String[] newWeekdays) {
  212.         weekdays = duplicate(newWeekdays);
  213.     }
  214.  
  215.     /**
  216.      * Gets short weekday strings. For example: "Sun", "Mon", etc.
  217.      * @return the short weekday strings.
  218.      */
  219.     public String[] getShortWeekdays() {
  220.         return duplicate(shortWeekdays);
  221.     }
  222.  
  223.     /**
  224.      * Sets short weekday strings. For example: "Sun", "Mon", etc.
  225.      * @param newShortWeekdays the new short weekday strings.
  226.      */
  227.     public void setShortWeekdays(String[] newShortWeekdays) {
  228.         shortWeekdays = duplicate(newShortWeekdays);
  229.     }
  230.  
  231.     /**
  232.      * Gets ampm strings. For example: "AM" and "PM".
  233.      * @return the weekday strings.
  234.      */
  235.     public String[] getAmPmStrings() {
  236.         return duplicate(ampms);
  237.     }
  238.  
  239.     /**
  240.      * Sets ampm strings. For example: "AM" and "PM".
  241.      * @param newAmpms the new ampm strings.
  242.      */
  243.     public void setAmPmStrings(String[] newAmpms) {
  244.         ampms = duplicate(newAmpms);
  245.     }
  246.  
  247.     /**
  248.      * Gets timezone strings.
  249.      * @return the timezone strings.
  250.      */
  251.     public String[][] getZoneStrings() {
  252.         String[][] aCopy = new String[zoneStrings.length][];
  253.         for (int i = 0; i < zoneStrings.length; ++i)
  254.             aCopy[i] = duplicate(zoneStrings[i]);
  255.         return aCopy;
  256.     }
  257.  
  258.     /**
  259.      * Sets timezone strings.
  260.      * @param newZoneStrings the new timezone strings.
  261.      */
  262.     public void setZoneStrings(String[][] newZoneStrings) {
  263.         String[][] aCopy = new String[newZoneStrings.length][];
  264.         for (int i = 0; i < newZoneStrings.length; ++i)
  265.             aCopy[i] = duplicate(newZoneStrings[i]);
  266.         zoneStrings = aCopy;
  267.     }
  268.  
  269.     /**
  270.      * Gets localized date-time pattern characters. For example: 'u', 't', etc.
  271.      * @return the localized date-time pattern characters.
  272.      */
  273.     public String getLocalPatternChars() {
  274.         return new String(localPatternChars);
  275.     }
  276.  
  277.     /**
  278.      * Sets localized date-time pattern characters. For example: 'u', 't', etc.
  279.      * @param newLocalPatternChars the new localized date-time
  280.      * pattern characters.
  281.      */
  282.     public void setLocalPatternChars(String newLocalPatternChars) {
  283.         localPatternChars = new String(newLocalPatternChars);
  284.     }
  285.  
  286.     /**
  287.      * Overrides Cloneable
  288.      */
  289.     public Object clone()
  290.     {
  291.         try
  292.         {
  293.             DateFormatSymbols other = (DateFormatSymbols)super.clone();
  294.             copyMembers(this, other);
  295.             return other;
  296.         } catch (CloneNotSupportedException e) {
  297.             throw new InternalError();
  298.         }
  299.     }
  300.  
  301.     /**
  302.      * Override hashCode.
  303.      * Generates a hash code for the DateFormatSymbols object.
  304.      */
  305.     public int hashCode() {
  306.         int hashcode = 0;
  307.         for (int index = 0; index < this.zoneStrings[0].length; ++index)
  308.             hashcode ^= this.zoneStrings[0][index].hashCode();
  309.         return hashcode;
  310.     }
  311.  
  312.     /**
  313.      * Override equals
  314.      */
  315.     public boolean equals(Object obj)
  316.     {
  317.         if (this == obj) return true;
  318.         if (obj == null || getClass() != obj.getClass()) return false;
  319.         DateFormatSymbols that = (DateFormatSymbols) obj;
  320.         return (Utility.arrayEquals(eras, that.eras)
  321.                 && Utility.arrayEquals(months, that.months)
  322.                 && Utility.arrayEquals(shortMonths, that.shortMonths)
  323.                 && Utility.arrayEquals(weekdays, that.weekdays)
  324.                 && Utility.arrayEquals(shortWeekdays, that.shortWeekdays)
  325.                 && Utility.arrayEquals(ampms, that.ampms)
  326.                 && Utility.arrayEquals(zoneStrings, that.zoneStrings)
  327.                 && Utility.arrayEquals(localPatternChars,
  328.                                        that.localPatternChars));
  329.     }
  330.  
  331.     // =======================privates===============================
  332.  
  333.     /**
  334.      * Useful constant for defining timezone offsets.
  335.      */
  336.     static final int millisPerHour = 60*60*1000;
  337.     
  338.     /**
  339.      * Cache to hold the LocaleElements and DateFormatZoneData ResourceBundles
  340.      * of a Locale.
  341.      */
  342.     private static final Hashtable cachedLocaleData = new Hashtable(3);
  343.     
  344.     private void initializeData(Locale desiredLocale)
  345.     {
  346.     int i;
  347.     ResourceBundle resource;
  348.     ResourceBundle zoneResource;
  349.     /* try the cache first */
  350.     ResourceBundle[] data = 
  351.         (ResourceBundle[]) cachedLocaleData.get(desiredLocale);
  352.     if (data == null) {   /* cache miss */
  353.         data = new ResourceBundle[2];
  354.         data[0] = ResourceBundle.getBundle
  355.         ("java.text.resources.LocaleElements", desiredLocale);
  356.         data[1] = ResourceBundle.getBundle
  357.         ("java.text.resources.DateFormatZoneData", desiredLocale);
  358.         /* update cache */
  359.         cachedLocaleData.put(desiredLocale, data);
  360.     }
  361.     resource = data[0];
  362.     zoneResource = data[1];
  363.  
  364.         eras = (String[])resource.getObject("Eras");
  365.         months = resource.getStringArray("MonthNames");
  366.         shortMonths = resource.getStringArray("MonthAbbreviations");
  367.         String[] lWeekdays = resource.getStringArray("DayNames");
  368.         weekdays = new String[8];
  369.         weekdays[0] = "";  // 1-based
  370.         for (i=0; i<lWeekdays.length; i++)
  371.             weekdays[i+1] = lWeekdays[i];
  372.         String[] sWeekdays = resource.getStringArray("DayAbbreviations");
  373.         shortWeekdays = new String[8];
  374.         shortWeekdays[0] = "";  // 1-based
  375.         for (i=0; i<sWeekdays.length; i++)
  376.             shortWeekdays[i+1] = sWeekdays[i];
  377.         ampms = resource.getStringArray("AmPmMarkers");
  378.         zoneStrings = (String[][])zoneResource.getObject("zoneStrings");
  379.         localPatternChars
  380.             = (String) zoneResource.getObject("localPatternChars");
  381.     }
  382.  
  383.     /**
  384.      * Package private: used by SimpleDateFormat
  385.      * Gets the index for the given time zone ID to obtain the timezone
  386.      * strings for formatting. The time zone ID is just for programmatic
  387.      * lookup. NOT LOCALIZED!!!
  388.      * @param ID the given time zone ID.
  389.      * @return the index of the given time zone ID.  Returns -1 if
  390.      * the given time zone ID can't be located in the DateFormatSymbols object.
  391.      * @see java.util.SimpleTimeZone
  392.      */
  393.     final int getZoneIndex (String ID)
  394.     {
  395.         for (int index=0; index<zoneStrings.length; index++)
  396.         {
  397.             if (ID.equalsIgnoreCase(zoneStrings[index][0])) return index;
  398.         }
  399.  
  400.         return -1;
  401.     }
  402.  
  403.     /**
  404.      * Clones an array of Strings.
  405.      * @param srcArray the source array to be cloned.
  406.      * @param count the number of elements in the given source array.
  407.      * @return a cloned array.
  408.      */
  409.     private final String[] duplicate(String[] srcArray)
  410.     {
  411.         String[] dstArray = new String[srcArray.length];
  412.         System.arraycopy(srcArray, 0, dstArray, 0, srcArray.length);
  413.         return dstArray;
  414.     }
  415.  
  416.     /**
  417.      * Clones all the data members from the source DateFormatSymbols to
  418.      * the target DateFormatSymbols. This is only for subclasses.
  419.      * @param src the source DateFormatSymbols.
  420.      * @param dst the target DateFormatSymbols.
  421.      */
  422.     private final void copyMembers(DateFormatSymbols src, DateFormatSymbols dst)
  423.     {
  424.         dst.eras = duplicate(src.eras);
  425.         dst.months = duplicate(src.months);
  426.         dst.shortMonths = duplicate(src.shortMonths);
  427.         dst.weekdays = duplicate(src.weekdays);
  428.         dst.shortWeekdays = duplicate(src.shortWeekdays);
  429.         dst.ampms = duplicate(src.ampms);
  430.         for (int i = 0; i < dst.zoneStrings.length; ++i)
  431.             dst.zoneStrings[i] = duplicate(src.zoneStrings[i]);
  432.         dst.localPatternChars = new String (src.localPatternChars);
  433.     }
  434.  
  435.     /**
  436.      * Compares the equality of the two arrays of String.
  437.      * @param current this String array.
  438.      * @param other that String array.
  439.      */
  440.     private final boolean equals(String[] current, String[] other)
  441.     {
  442.         int count = current.length;
  443.  
  444.         for (int i = 0; i < count; ++i)
  445.             if (!current[i].equals(other[i]))
  446.                 return false;
  447.         return true;
  448.     }
  449.  
  450. }
  451.